package cx3k.scheduler.wrappers;

import java.util.ArrayList;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


import cx3k.dataaccess.search.Searcher;
import cx3k.dataaccess.search.Searcher.SearchField;
import cx3k.scheduler.objects.GroupedCourse;


@SuppressWarnings("unchecked")
public class GroupedCourseWrapper {

	
	private static Map<String, List<GroupedCourse>> prereqsMap = new HashMap<String, List<GroupedCourse>>();
//	private static Map<String,GroupedCourse> temp = new HashMap<String, GroupedCourse>();
//	static{
	static {	
		Searcher searcher = new Searcher(GroupedCourse.class);
		List<GroupedCourse> results = (List<GroupedCourse>) searcher.execute();
		
		Map<String,GroupedCourse> temp = new HashMap<String, GroupedCourse>();
		for(GroupedCourse course : results){
			temp.put(getCourseName(course), course);
		}
		
		Iterator<GroupedCourse> iterator = results.iterator();
		GroupedCourse course;
		
		while(iterator.hasNext()){
			course = iterator.next();
			
			prereqsMap.put(getCourseName(course), new LinkedList<GroupedCourse>());
			
			for(String prereq : course.getPreReqs().split(",")){
				if(temp.get(prereq) != null){
					if(!prereqsMap.get(getCourseName(course)).contains(temp.get(prereq))){
						prereqsMap.get(getCourseName(course)).add(temp.get(prereq));
					}
					
				}
			}
		}
		
		for(Map.Entry<String, List<GroupedCourse>> entry : prereqsMap.entrySet()){
			System.out.print("key = " + entry.getKey() + " values =");
			for(GroupedCourse c : entry.getValue()){
				System.out.print(" " + c.getDegreeProgram() + c.getCourseNum());
			}
			System.out.println();
		}
		
		
		
	}
	
	private static String getCourseName(GroupedCourse course){
		return course.getDegreeProgram() + course.getCourseNum();
	}
	
	private GroupedCourse course;
//	private List<GroupedCourse> preReqs;
	
	public GroupedCourseWrapper(GroupedCourse course){
		this.course = course;
//		init();
//		this.preReqs = generatePrereqs();
//		this.preReqs = 
	}
	
	public List<GroupedCourse> getPreReqs(){
//		return preReqs;
		return prereqsMap.get(getCourseName(getCourse()));
//		return generatePrereqs();
	}
	
	public void addPreReq(GroupedCourse preReq){
		getPreReqs().add(preReq);
	}
	
	public GroupedCourse getCourse(){
		return course;
	}
	
	public static void main(String[] args){
		Searcher searcher = new Searcher(GroupedCourse.class);
		searcher.searchForExactValue(SearchField.GROUPED_COURSE_DEGREE_PROGRAM, "CMSC");
		searcher.searchForExactValue(SearchField.GROUPED_COURSE_COURSE_NUM, "432");
		
		try{
		GroupedCourse course = ((List<GroupedCourse>) searcher.execute()).get(0);
		GroupedCourseWrapper wrapper = new GroupedCourseWrapper(course);
		for(GroupedCourse temp : wrapper.getPreReqs()){
			System.out.println(temp.getDegreeProgram() + temp.getCourseNum());
		}
		}catch(Throwable e){
//			System.err.println(e.getLocalizedMessage());
			
		}
	}
	
	private List<GroupedCourse> getAllPreReqsFor(GroupedCourse course){
		List<GroupedCourse> thisCoursesPrereqs = prereqsMap.get(getCourseName(course));
		List<GroupedCourse> allPreReqs = new ArrayList<GroupedCourse>();
		allPreReqs.addAll(thisCoursesPrereqs);
		
		for(GroupedCourse aCourse : thisCoursesPrereqs){
			for(GroupedCourse other : getAllPreReqsFor(aCourse)){
				if(!allPreReqs.contains(other)){
					allPreReqs.add(other);
				}
			}
		}
		
		return allPreReqs;
	}
	
	
	private List<GroupedCourse> generatePrereqs(){
		
		return getAllPreReqsFor(getCourse());
		
		/*String[] prereqs = getCourse().getPreReqs().split(",");
		List<GroupedCourse> reqs = new ArrayList<GroupedCourse>(prereqs.length);
			
		for(String courseName : prereqs){
			if(temp.get(courseName) != null)
				reqs.add(temp.get(courseName));
		}
		
		return reqs;*/
		
		/*String[] prereqs = getCourse().getPreReqs().split(",");
		List<GroupedCourse> reqs = new ArrayList<GroupedCourse>(prereqs.length);
		List<?> results;
		
		
		Searcher searcher;
		
		String courseNum;
		String degreeProgram;
		
		for(String course : prereqs){			
			if(course != null && course.length() >= 4){
				searcher = new Searcher(GroupedCourse.class);
				
				degreeProgram = course.substring(0, 4);
				courseNum = course.substring(4);
				
				searcher.searchForExactValue(SearchField.GROUPED_COURSE_DEGREE_PROGRAM, degreeProgram);
				searcher.searchForExactValue(SearchField.GROUPED_COURSE_COURSE_NUM, courseNum);
				searcher.searchForExactValue(SearchField.MAJOR_ID, ((Integer) getCourse().getRequirementGrouping().getMajor().getMajorId()).toString());
				
				results = searcher.execute();
				
				if(!results.isEmpty()){
					Object[] objs = ((Object[]) results.get(0));
					reqs.add((GroupedCourse) objs[0]);
				}
			}
		}
		
		
		return reqs;*/
	}
	
	
	
	
}
